home *** CD-ROM | disk | FTP | other *** search
- {*******************************************************
- TNodes [Nodes unit]
-
- This unit contains the code for the TNode base class, the
- TBooleanNode and the TEndNode.
-
- A TBooleanNode accepts input at run-time and compares it to
- the Criteria property. If the boolean result is yes the input
- is passed to the node connected to the YesPipe property and
- if no the input is passed to NoPipe. Finally, the Run method
- for either YesPipe or NoPipe is called.
-
- A TEndNode is designed to connect at the end of each possible
- path that a given input could take. TEndNode implements an
- AfterRun event which allows a simple way of indicating where
- the input ended. There is also a ResultStr property which,
- along with the AfterRun method provides a mechanism for
- reporting results.
-
- This scheme allows the developer to create a decision tree of any
- size and structure at design time. At run-time all you need do is
- provide input to BooleanNode1 and call its Run method. Each
- TEndNode in your structure would have its AfterRun event connected
- to a method which could perform any action desired. Most commonly
- this would be a method to display the ResultStr of the TEndNode
- which actually called the method. The code would look like this.
-
- procedure TForm1.EndNode1AfterRun(Sender: TObject);
- begin
- Label1.Caption := (Sender as TEndNode).ResultStr;
- end;
-
- I hope you find this code useful. If you make improvements please
- e-mail me a copy. Enjoy.
-
- Paul Warren
- HomeGrown Software Development
- (c) 1995 Langley British Columbia.
- (604) 530-9097
- e-mail: hg_soft@uniserve.com
- Home page: http://haven.uniserve.com/~hg_soft
-
- ********************************************************}
-
- unit Nodes;
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, EnhEdits, StrLib;
-
- type
- TNode = class(TComponent)
- private
- Input: real;
- FInputAsReal: real;
- FYesPipe: TNode;
- FNoPipe: TNode;
- procedure SetInputAsReal(NewValue: real);
- function GetInputAsReal: real;
- procedure Run; virtual; abstract;
- public
- { Public declarations }
- property InputAsReal: real read GetInputAsReal write SetInputAsReal;
- {property Input: TRealStr read FInput write FInput;}
- published
- { Published declarations }
- end;
-
- TOperator = (opEquals, opGreaterThan, opGreaterOrEqual, opLessThan, opLessOrEqual);
-
- TBooleanNode = class(TNode)
- private
- { Private declarations }
- FCritAsReal: real;
- FEnabled: Boolean;
- FCriteria: TRealStr;
- FOperator: TOperator;
- procedure SetCritAsReal(NewValue: real);
- function GetCritAsReal: real;
- protected
- { Protected declarations }
- public
- { Public declarations }
- constructor Create(AOwner: TComponent); override;
- procedure Run; override;
- property CritAsReal: real read GetCritAsReal write SetCritAsReal;
- published
- { Published declarations }
- property Enabled: Boolean read FEnabled write FEnabled default True;
- property Criteria: TRealStr read FCriteria write FCriteria;
- property Operator: TOperator read FOperator write FOperator;
- property YesPipe: TNode read FYesPipe write FYesPipe;
- property NoPipe: TNode read FNoPipe write FNoPipe;
- end;
-
- TEndNode = class(TNode)
- private
- { Private declarations }
- FIsResult: boolean;
- FResultStr: string;
- FAfterRun: TNotifyEvent;
- procedure SetAfterRun(Value: TNotifyEvent);
- protected
- { Protected declarations }
- procedure After; dynamic;
- public
- { Public declarations }
- constructor Create(AOwner: TComponent); override;
- procedure Run; override;
- published
- { Published declarations }
- property IsResult: Boolean read FIsResult write FIsResult default false;
- property ResultStr: string read FResultStr write FResultStr;
- property AfterRun: TNotifyEvent read FAfterRun write SetAfterRun;
- end;
-
- procedure Register;
-
- implementation
-
- { Methods to Get and Set the Input property
- as a real type }
- function TNode.GetInputAsReal: real;
- var
- code: integer;
- begin
- try
- Result := Input;
- except
- end;
- end;
-
- procedure TNode.SetInputAsReal(NewValue: real);
- begin
- try
- Input := NewValue;
- except
- end;
- end;
-
- { construct TBooleanNode }
- constructor TBooleanNode.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FEnabled := true;
- FYesPipe := nil;
- FNoPipe := nil;
- end;
-
- { Methods to Get and Set the Criteria property
- as a real type }
- function TBooleanNode.GetCritAsReal: real;
- var
- code: integer;
- begin
- try
- Result := StrToReal(code, Criteria);
- except
- end;
- end;
-
- procedure TBooleanNode.SetCritAsReal(NewValue: real);
- begin
- try
- Criteria := RealToStr(NewValue, 2);
- except
- end;
- end;
-
- { Run method. Compares Input to criteria and passes
- Input to YesPipe or NoPipe. Calls Run for YesPipe
- or NoPipe }
- procedure TBooleanNode.Run;
- begin
- case operator of
- opEquals: if InputAsReal = CritAsReal then
- begin
- YesPipe.InputAsReal := Input;
- YesPipe.Run;
- end else
- begin
- NoPipe.InputAsReal := Input;
- NoPipe.Run;
- end;
- opGreaterThan: if InputAsReal > CritAsReal then
- begin
- YesPipe.InputAsReal := Input;
- YesPipe.Run;
- end else
- begin
- NoPipe.InputAsReal := Input;
- NoPipe.Run;
- end;
- opGreaterOrEqual: if InputAsReal >= CritAsReal then
- begin
- YesPipe.InputAsReal := Input;
- YesPipe.Run;
- end else
- begin
- NoPipe.InputAsReal := Input;
- NoPipe.Run;
- end;
- opLessThan: if InputAsReal < CritAsReal then
- begin
- YesPipe.InputAsReal := Input;
- YesPipe.Run;
- end else
- begin
- NoPipe.InputAsReal := Input;
- NoPipe.Run;
- end;
- opLessOrEqual: if InputAsReal <= CritAsReal then
- begin
- YesPipe.InputAsReal := Input;
- YesPipe.Run;
- end else
- begin
- NoPipe.InputAsReal := Input;
- NoPipe.Run;
- end;
- end;
- end;
-
- { construct TEndNode }
- constructor TEndNode.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FIsResult := false;
- end;
-
- { Set AfterRun event }
- procedure TEndNode.SetAfterRun(Value: TNotifyEvent);
- begin
- FAfterRun := Value;
- end;
-
- { implement AfterRun event }
- procedure TEndNode.After;
- begin
- if Assigned(FAfterRun) then FAfterRun(Self);
- FIsResult := false;
- end;
-
- { Run method. Just causes AfterRun event to be Run.
- IsResult is there for polling TEndNodes for the
- result. Not very useful }
- procedure TEndNode.Run;
- begin
- FIsResult := true;
- After;
- end;
-
- { Register components }
- procedure Register;
- begin
- RegisterComponents('Misc', [TBooleanNode]);
- RegisterComponents('Misc', [TEndNode]);
- end;
-
- end.
-